package com.ybwh.springboot2.common.auth;

import com.ybwh.springboot2.common.RespData;
import com.ybwh.springboot2.common.annotation.LoginRequired;
import com.ybwh.springboot2.util.HttpWebUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录验证拦截
 */
public abstract class LoginRequiredInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        LoginRequired loginRequired = handlerMethod.getMethodAnnotation(LoginRequired.class);
        if (null == loginRequired) {
            loginRequired = handlerMethod.getBeanType().getAnnotation(LoginRequired.class);
        }

        if (null == loginRequired) {
            return true;
        }

        boolean result = validLoginRequired(request, response, loginRequired);

        if (!result) {
            HttpWebUtil.respJson(response, RespData.reLoginResp());
            return false;
        }

        String funcCode = loginRequired.authCode();
        if (StringUtils.isBlank(funcCode)) {
            return true;
        }

        Long userId = getUserId(request);

        result = validFuncAccess(funcCode, userId);

        return result;
    }

    /**
     * 验证用户是否有权限访问controller方法，不需要此功能则直接返回true即可
     *
     * @param funcCode
     * @param userId
     * @return
     */
    protected abstract boolean validFuncAccess(String funcCode, Long userId);

    /**
     * 获取用户ID
     *
     * @param request
     * @return
     */
    protected abstract Long getUserId(HttpServletRequest request);


    /**
     * 验证是否登录
     *
     * @param request
     * @param response
     * @param loginRequired
     * @return
     */
    protected abstract boolean validLoginRequired(HttpServletRequest request, HttpServletResponse response, LoginRequired loginRequired);
}
